package com.gxy.learn.thread.example.abcdef;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: Condition（条件变量）:通常与一个锁关联。需要在多个Contidion中共享一个锁时，可以传递一个Lock/RLock实例给构造方法，否则它将自己生成一个RLock实例。
 * <p>
 * Condition中await()方法类似于Object类中的wait()方法。
 * Condition中await(long time,TimeUnit unit)方法类似于Object类中的wait(long time)方法。
 * Condition中signal()方法类似于Object类中的notify()方法。
 * Condition中signalAll()方法类似于Object类中的notifyAll()方法。
 * 应用场景：Condition是一个多线程间协调通信的工具类，使得某个，或者某些线程一起等待某个条件（Condition）,只有当该条件具备( signal 或者 signalAll方法被调用)时 ，这些等待线程才会被唤醒，从而重新争夺锁。
 * @author: gaoxueyong
 * @Date: 2022/11/10 15:52
 */
@Slf4j
public class ThreadConditionTest {
    private static Lock lock = new ReentrantLock();
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();


    public static void main(String[] args) {
        char[] a1 = "12345".toCharArray();
        char[] a2 = "abcde".toCharArray();
        new Thread(() -> {
            lock.lock();
            try {
                for (char a : a1) {
                    log.info(String.valueOf(a));
//                    先唤醒condition2再阻塞condition1
                    condition2.signal();
                    condition1.await();
                }
            } catch (Exception e) {
                log.error("err", e);
            } finally {
                lock.unlock();
            }
        }).start();

        new Thread(() -> {
            lock.lock();
            try {
                for (char a : a2) {
                    log.info(String.valueOf(a));
//                    先唤醒condition1再阻塞condition2
                    condition1.signal();
                    condition2.await();
                }
            } catch (Exception e) {
                log.error("err", e);
            } finally {
                lock.unlock();
            }
        }).start();
    }
}
